using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Serialization;
using WindowsFormsApplication1.WebTest;
using WindowsFormsApplication1.WebTest.New;
using WindowsFormsApplication1.WebTest.WebTestXmlNodes;
using WindowsFormsApplication1.WebTest.WebTestXmlNodes.New;

namespace WindowsFormsApplication1
{
    public abstract class GenericWebTestNode : TreeNode, ICustomTypeDescriptor
    {
        protected const string XmlNamespace = "http://microsoft.com/schemas/VisualStudio/TeamTest/2006";

        protected NodeDescriptionPropertiesCollection _nodeProperties = new NodeDescriptionPropertiesCollection();

        protected readonly XmlSerializer _validationRulesNodeSerializer = new XmlSerializer(typeof(ValidationRulesNode));
        protected readonly XmlSerializer _validationRuleNodeSerializer = new XmlSerializer(typeof(ValidationRuleNode));
        protected readonly XmlSerializer _itemsNodeSerializer = new XmlSerializer(typeof(ItemsNode));
        protected readonly XmlSerializer _requestNodeSerializer = new XmlSerializer(typeof(RequestNode));
        protected readonly XmlSerializer _stringHttpBodyNodeSerializer = new XmlSerializer(typeof(StringHttpBodyNode));
        protected readonly XmlSerializer _extractionRuleNodeSerializer = new XmlSerializer(typeof(ExtractionRuleNode));
        protected readonly XmlSerializer _ruleParametersNodeSerializer = new XmlSerializer(typeof(RuleParametersNode));
        protected readonly XmlSerializer _extractionRulesNodeSerializer = new XmlSerializer(typeof(ExtractionRulesNode));
        protected readonly XmlSerializer _fileUploadParameterNodeSerializer = new XmlSerializer(typeof(FileUploadParameterNode));
        protected readonly XmlSerializer _formPostParameterNodeSerializer = new XmlSerializer(typeof(FormPostParameterNode));
        protected readonly XmlSerializer _queryStringParameterNodeSerializer = new XmlSerializer(typeof(QueryStringParameterNode));
        protected readonly XmlSerializer _requestPluginNodeSerializer = new XmlSerializer(typeof(RequestPluginNode));
        protected readonly XmlSerializer _queryStringParametersNodeSerializer = new XmlSerializer(typeof(QueryStringParametersNode));
        protected readonly XmlSerializer _formPostHttpBodyNodeSerializer = new XmlSerializer(typeof(FormPostHttpBodyNode));
        protected readonly XmlSerializer _requestPluginsNodeSerializer = new XmlSerializer(typeof(RequestPluginsNode));
        protected readonly XmlSerializer _correlationExtractionRulesNodeSerializer = new XmlSerializer(typeof(CorrelationExtractionRulesNode));
        protected readonly XmlSerializer _commentNodeSerializer = new XmlSerializer(typeof(CommentNode));
        protected readonly XmlSerializer _dependentRequestsNodeSerializer = new XmlSerializer(typeof(DependentRequestsNode));
        protected readonly XmlSerializer _headerNodeSerializer = new XmlSerializer(typeof(HeaderNode));
        protected readonly XmlSerializer _headersNodeSerializer = new XmlSerializer(typeof(HeadersNode));
        protected readonly XmlSerializer _includedWebTestNodeSerializer = new XmlSerializer(typeof(IncludedWebTestNode));
        protected readonly XmlSerializer _transactionTimerNodeSerializer = new XmlSerializer(typeof(TransactionTimerNode));
        protected readonly XmlSerializer _webTestPluginNodeSerializer = new XmlSerializer(typeof(WebTestPluginNode));
        protected readonly XmlSerializer _contextParameterNodeSerializer = new XmlSerializer(typeof(ContextParameterNode));
        protected readonly XmlSerializer _dataSourceTableNodeSerializer = new XmlSerializer(typeof(DataSourceTableNode));
        protected readonly XmlSerializer _tablesNodeSerializer = new XmlSerializer(typeof(TablesNode));
        protected readonly XmlSerializer _dataSourceNodeSerializer = new XmlSerializer(typeof(DataSourceNode));
        protected readonly XmlSerializer _contextParametersNodeSerializer = new XmlSerializer(typeof(ContextParametersNode));
        protected readonly XmlSerializer _webTestPluginsNodeSerializer = new XmlSerializer(typeof(WebTestPluginsNode));
        protected readonly XmlSerializer _dataSourcesNodeSerializer = new XmlSerializer(typeof(DataSourcesNode));



        public void ReadXmlAttributes(XmlReader reader)
        {
            Notification.BeginOperation("Reading XML attributes for " + reader.Name, NodeOperationEventArgs.EventImportance.Debug);

            if (reader.AttributeCount == 0)
            {
                Notification.EndOperation();
                return;
            }

            reader.MoveToFirstAttribute();
            do
            {
                NodeDescriptionProperties nodeProperties = new NodeDescriptionProperties(this)
                                                               {
                                                                   Value = reader.Value,
                                                                   Name = reader.Name,
                                                                   WebTestNodeType = NodeDescriptionProperties.WebTestNodeTypes.Attribute
                                                               };

                _nodeProperties.Add(nodeProperties.Name, nodeProperties);

            } while (reader.MoveToNextAttribute());

            Notification.EndOperation();
        }


        public void ReadXml(XmlReader reader)
        {
            Notification.BeginOperation("Processing " + GetType().Name + " Node", NodeOperationEventArgs.EventImportance.Detailed);

            //Read element attributes
            ReadXmlAttributes(reader);

            //Set node properties such as Icon, Text, etc..
            SetNodeProperties();

            //Move to the next node; this will read empty tag </TagName>
            reader.MoveToContent();
            bool isEmptyElement = reader.IsEmptyElement;

            reader.Read();

            //If there is closing tag read it
            if (!isEmptyElement)
                reader.ReadEndElement();

            Notification.EndOperation();
        }

        public void WriteXml(XmlWriter writer)
        {
        }

        public virtual void SetNodeProperties()
        {
            //Set the node icon
            SelectedImageIndex = 4;
            ImageIndex = 4;

            //Set the node text/name
            Text = "Unknown node type";
        }

        public NodeDescriptionPropertiesCollection NodeProperties
        {
            get { return _nodeProperties; }
            set { _nodeProperties = value; }
        }


        #region ICustomTypeDescriptor Members

        public String GetClassName()
        {
            return TypeDescriptor.GetClassName(this, true);
        }

        public AttributeCollection GetAttributes()
        {
            return TypeDescriptor.GetAttributes(this, true);
        }

        public String GetComponentName()
        {
            return TypeDescriptor.GetComponentName(this, true);
        }

        public TypeConverter GetConverter()
        {
            return TypeDescriptor.GetConverter(this, true);
        }

        public EventDescriptor GetDefaultEvent()
        {
            return TypeDescriptor.GetDefaultEvent(this, true);
        }

        public PropertyDescriptor GetDefaultProperty()
        {
            return TypeDescriptor.GetDefaultProperty(this, true);
        }

        public object GetEditor(Type editorBaseType)
        {
            return TypeDescriptor.GetEditor(this, editorBaseType, true);
        }

        public EventDescriptorCollection GetEvents(Attribute[] attributes)
        {
            return TypeDescriptor.GetEvents(this, attributes, true);
        }

        public EventDescriptorCollection GetEvents()
        {
            return TypeDescriptor.GetEvents(this, true);
        }

        public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
        {
            return GetProperties();
        }

        public object GetPropertyOwner(PropertyDescriptor pd)
        {
            return this;
        }

        public PropertyDescriptorCollection GetProperties()
        {
            // Create a new collection object PropertyDescriptorCollection

            PropertyDescriptorCollection pds = new PropertyDescriptorCollection(null);

            // Iterate the list NodeProperties
            foreach (var propertyName in NodeProperties.Keys)
            {
                // For each property create a property descriptor 

                // and add it to the 

                // PropertyDescriptorCollection instance

                DictionaryPropertyDescriptor pd = new
                    DictionaryPropertyDescriptor(NodeProperties, propertyName);
                pds.Add(pd);
            }
            return pds;

        }


        #endregion



    }
}